<?php

namespace App\Modules\Crowd\Models;

use App\Exceptions\StandardException;
use App\Library\Lock;
use App\Modules\Order\Models\SupportOrder;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Ramsey\Uuid\Uuid;

/**
 * Class Crowd
 * @package App\Modules\Crowd\Models
 * @property string $no
 * @property int $shop_id
 * @property string $cover
 * @property int $user_id
 * @property string $title
 * @property int $link_id
 * @property array $detail
 * @property int $number
 * @property int $price
 * @property int $support_money
 * @property int $self_pay
 * @property string $last_support_time
 * @property string $status
 * @property int $referrer_id
 */
class Crowd extends Model
{
    const TYPE_PACKAGE = "package";
    const TYPE_GOOD = "good";

    const STATUS_PROGRESSION = "progressing";
    const STATUS_FINISH = "finish";
    const STATUS_REFUND = "refund";

    public static $showStatus = [
        self::STATUS_PROGRESSION => '进行中',
        self::STATUS_FINISH => '完成',
        self::STATUS_REFUND => '已退款',
    ];
    protected $fillable = [
        'no',
        'shop_id',
        'user_id',
        'cover',
        'title',
        'link_id',
        'detail',
        'number',
        'price',
        'support_money',
        'self_pay',
        'last_support_time',
        'status',
        'referrer_id',
    ];

    protected $casts = [
        'detail' => "array",
    ];

    public static function getNo()
    {
        return Uuid::uuid4()->getHex();
    }

    public function getLast()
    {
        return $this->price - $this->support_money - $this->self_pay;
    }
    public function support($userId, $money)
    {
        Lock::lock("crowd:{$this->id}", 2, function () use($userId, $money) {
            $this->refresh();
            if ($this->getLast() < $money) {
                throw new StandardException('超出众筹金额');
            }
            if ($this->status != self::STATUS_PROGRESSION) {
                throw new StandardException('众筹状态异常');
            }
            if ($userId == $this->user_id) {
                $this->self_pay += $money;
            } else {
                $this->support_money += $money;
            }
            if ($this->getLast() == 0) {
                $this->status = self::STATUS_FINISH;
            }
            $this->last_support_time = Carbon::now()->toDateTimeString();
            $this->save();
        });
    }

    public function refund()
    {
        $supportList = SupportOrder::query()
            ->where('crowd_id', $this->id)
            ->where('status', SupportOrder::STATUS_SUCCESS)
            ->get()
            ->each(function (SupportOrder $item) {
                $item->refund();
            });
        $this->status = self::STATUS_REFUND;
        $this->save();
    }
}
